﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using XFPPT.NET.Models;

namespace XFPPT.NET
{
    /// <summary>
    /// 智能PPT生成V2版本
    /// </summary>
    public class XFPPTv2ApiClient: ApiClientBase
    {
        /// <summary>
        /// 智能PPT生成V2版本
        /// </summary>
        public XFPPTv2ApiClient() : base() { }

        /// <summary>
        /// 智能PPT生成V2版本
        /// </summary>
        /// <param name="appId">应用ID</param>
        /// <param name="secret">应用的秘钥</param>
        /// <param name="url">地址默认:https://zwapi.xfyun.cn/</param>
        public XFPPTv2ApiClient(string appId, string secret, string url = "https://zwapi.xfyun.cn/") : base(appId, secret, url) { }

        /// <summary>
        /// PPT主题列表查询异步
        /// </summary>
        /// <param name="style">风格类型： "简约","卡通","商务","创意","国风","清新","扁平","插画","节日"</param>
        /// <param name="color">颜色类型： "蓝色","绿色","红色","紫色","黑色","灰色","黄色","粉色","橙色"</param>
        /// <param name="industry">行业类型： "科技互联网","教育培训","政务","学院","电子商务","金融战略","法律","医疗健康","文旅体育","艺术广告","人力资源","游戏娱乐"</param>
        /// <param name="pageNum">页数</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        public async Task<TemplateListResponse> GetTemplateListAsync(string style="", string color="",string industry="",long pageNum = 1, long pageSize = 10)
        {
            System.Text.Json.Nodes.JsonObject RequestObject = new System.Text.Json.Nodes.JsonObject();
            RequestObject.Add("style", style);
            RequestObject.Add("color", color);
            RequestObject.Add("industry", industry);
            RequestObject.Add("pageNum", pageNum.ToString());
            RequestObject.Add("pageSize", pageSize.ToString());
            string requestjson = System.Text.Json.JsonSerializer.Serialize(RequestObject, JsonSerializerOptions);
            string url = Url + "api/ppt/v2/template/list";
            string resjosn = await SendRequestAsync(method:HttpMethod.Post,url: url,postData: requestjson);
            TemplateListResponse  templateListResponse = new TemplateListResponse();
            templateListResponse.RealJsonstring = resjosn;
            return templateListResponse;
        }

        /// <summary>
        /// PPT主题列表查询
        /// </summary>
        /// <param name="style">风格类型： "简约","卡通","商务","创意","国风","清新","扁平","插画","节日"</param>
        /// <param name="color">颜色类型： "蓝色","绿色","红色","紫色","黑色","灰色","黄色","粉色","橙色"</param>
        /// <param name="industry">行业类型： "科技互联网","教育培训","政务","学院","电子商务","金融战略","法律","医疗健康","文旅体育","艺术广告","人力资源","游戏娱乐"</param>
        /// <param name="pageNum">页数</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>

        public TemplateListResponse GetTemplateList(string style = "", string color = "", string industry = "", long pageNum = 1, long pageSize = 10)
        {

            Task<TemplateListResponse> task = GetTemplateListAsync(style, color, industry, pageNum, pageSize);
            task.Wait();
            return task.Result;
        }

        /// <summary>
        /// PPT生成 Async（直接根据用户输入要求，获得最终PPT）
        /// </summary>
        /// <param name="pPTCreateRequest"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public async Task<PPTCreateResponse> PPTCreateAsync(PPTCreateRequest pPTCreateRequest)
        {

           
            if (pPTCreateRequest == null)
            {
                throw new ArgumentNullException("PPTCreateRequest is not null");
            }
           
            MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.query))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.query!), "query");

            }

            if (pPTCreateRequest.file!=null)
            {
                if (string.IsNullOrWhiteSpace(pPTCreateRequest.fileName))
                {
                    throw new ArgumentNullException("File name (with file extension; if file or fileUrl is provided, fileName is required).");
                }
                var fileContent = new ByteArrayContent(pPTCreateRequest.file!);
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
                multipartFormDataContent.Add(fileContent, "file", pPTCreateRequest.fileName!);
            }

       
            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.fileUrl))
            {
                if (string.IsNullOrWhiteSpace(pPTCreateRequest.fileName))
                {
                    throw new ArgumentNullException("File name (with file extension; if file or fileUrl is provided, fileName is required).");
                }
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.fileUrl), "fileUrl");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.fileName))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.fileName), "fileName");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.templateId))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.templateId), "templateId");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.businessId))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.businessId), "businessId");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.author))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.author), "author");
            }

            if (pPTCreateRequest.isCardNote.HasValue)
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.isCardNote.Value.ToString()), "isCardNote");
            }

            if (pPTCreateRequest.search.HasValue)
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.search.Value.ToString()), "search");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.language))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.language), "language");
            }

            if (pPTCreateRequest.isFigure.HasValue)
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.isFigure.Value.ToString()), "isFigure");
            }

            if (!string.IsNullOrWhiteSpace(pPTCreateRequest.aiImage))
            {
                multipartFormDataContent.Add(new StringContent(pPTCreateRequest.aiImage), "aiImage");
            }



            string url = Url + "api/ppt/v2/create";
            string resjosn = await SendRequestByFormDataAsync(url:url,multipartFormData: multipartFormDataContent);
            PPTCreateResponse pPTCreateResponse = new PPTCreateResponse();
            pPTCreateResponse.RealJsonstring = resjosn;
            return pPTCreateResponse;
        }

        /// <summary>
        /// PPT生成 （直接根据用户输入要求，获得最终PPT）
        /// </summary>
        /// <param name="pPTCreateRequest"></param>
        /// <returns></returns>
        public PPTCreateResponse PPTCreate(PPTCreateRequest pPTCreateRequest)
        {

            Task<PPTCreateResponse> task = PPTCreateAsync(pPTCreateRequest);
            task.Wait();
            return task.Result;
        }

        /// <summary>
        /// PPT进度查询 async
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public async Task<ProgressResponse> GetProgressAsync(string sid)
        {
            Dictionary<string, string> queryParameters=new Dictionary<string, string>();
            queryParameters.Add("sid", sid);
            string url = Url + "api/ppt/v2/progress";
            string resjosn = await SendRequestAsync(method: HttpMethod.Get, url: url, queryParameters: queryParameters);
            ProgressResponse progressResponse = new ProgressResponse();
            progressResponse.RealJsonstring = resjosn;
            return progressResponse;
        }
     
        /// <summary>
        /// PPT进度查询
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public ProgressResponse GetProgress(string sid)
        {

            Task<ProgressResponse> task = GetProgressAsync(sid);
            task.Wait();
            return task.Result;
        }

        /// <summary>
        /// 异步创建PPT大纲的方法。该方法通过POST请求以multipart/form-data格式向指定API发送数据，获取PPT大纲响应。
        /// This method is used to asynchronously create a PPT outline. It sends a POST request with multipart/form-data to the specified API to get the PPT outline response.
        /// </summary>
        /// <param name="query">用户生成PPT的要求，最多8000字，不能为空字符串或仅包含空格的字符串。The user's requirements for creating a PPT, with a maximum of 8000 characters. It cannot be an empty string or a string containing only spaces.</param>
        /// <param name="businessId">业务ID，非必传参数，业务方自行决定是否使用。The business ID, which is an optional parameter. The business party can decide whether to use it.</param>
        /// <param name="language">语种，非必传参数，默认为'cn'。The language, which is an optional parameter. The default value is 'cn'.</param>
        /// <param name="search">是否联网搜索，非必传参数，默认为false。Whether to search online, which is an optional parameter. The default value is false.</param>
        /// <returns>返回一个表示PPT大纲创建响应的异步任务。Returns an asynchronous task representing the PPT outline creation response.</returns>
        public async Task<CreateOutlineResponse> CreateOutlineAsync(string query,string? businessId ="",string? language ="",bool? search =null)
        {
            MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
            if (!string.IsNullOrWhiteSpace(query))
            {
                multipartFormDataContent.Add(new StringContent(query), "query");

            }
            if (!string.IsNullOrWhiteSpace(businessId))
            {
                multipartFormDataContent.Add(new StringContent(businessId), "businessId");
            }
            if (!string.IsNullOrWhiteSpace(language))
            {
                multipartFormDataContent.Add(new StringContent(language), "language");
            }
            if (search.HasValue)
            {
                multipartFormDataContent.Add(new StringContent(search.Value.ToString()), "search");
            }

            string url = Url + "api/ppt/v2/createOutline";
            string resjosn = await SendRequestByFormDataAsync(url: url, multipartFormData: multipartFormDataContent);
            CreateOutlineResponse pPTCreateOutlineResponse = new CreateOutlineResponse();
            pPTCreateOutlineResponse.RealJsonstring = resjosn;
            return pPTCreateOutlineResponse;
        }
      
        /// <summary>
        /// 同步创建PPT大纲的方法。该方法调用异步的PPTCreateOutlineAsync方法，并等待其完成以实现同步调用。
        /// This method is used to synchronously create a PPT outline. It calls the asynchronous PPTCreateOutlineAsync method and waits for its completion to achieve a synchronous call.
        /// </summary>
        /// <param name="query">用户生成PPT的要求，最多8000字，不能为空字符串或仅包含空格的字符串。The user's requirements for creating a PPT, with a maximum of 8000 characters. It cannot be an empty string or a string containing only spaces.</param>
        /// <param name="businessId">业务ID，非必传参数，业务方自行决定是否使用。The business ID, which is an optional parameter. The business party can decide whether to use it.</param>
        /// <param name="language">语种，非必传参数，默认为'cn'。The language, which is an optional parameter. The default value is 'cn'.</param>
        /// <param name="search">是否联网搜索，非必传参数，默认为false。Whether to search online, which is an optional parameter. The default value is false.</param>
        /// <returns>返回一个表示PPT大纲创建响应的对象。Returns an object representing the PPT outline creation response.</returns>
        public CreateOutlineResponse CreateOutline(string query, string? businessId = "", string? language = "", bool? search = null)
        {

            Task<CreateOutlineResponse> task = CreateOutlineAsync(query, businessId, language, search);
            task.Wait();
            return task.Result;
        }


        /// <summary>
        /// 基于用户提示、文档等相关内容异步生成PPT大纲。
        /// This method asynchronously generates a PPT outline based on user prompts, documents, and other relevant content.
        /// </summary>
        /// <param name="createOutlineByDoc">包含生成PPT大纲所需参数的请求对象。The request object containing the parameters required to generate the PPT outline.</param>
        /// <returns>生成PPT大纲的响应对象。The response object for generating the PPT outline.</returns>
        /// <remarks>
        /// query参数不得超过8000字，上传文件支持pdf(不支持扫描件)、doc、docx、txt、md格式的文件，注意：txt格式限制100万字以内，其他文件限制10M。
        /// The query parameter should not exceed 8000 characters. Supported file formats for upload are pdf (scanned copies are not supported), doc, docx, txt, and md. Note that txt files are limited to within 1 million characters, and other files are limited to 10M.
        /// </remarks>
        public async Task<CreateOutlineByDocResponse> CreateOutlineByDocAsync(CreateOutlineByDocRequest createOutlineByDoc)
        {
            if (createOutlineByDoc == null)
            {
                throw new ArgumentNullException("CreateOutlineByDocRequest is not null");
            }

            // 检查 file 和 fileUrl 是否同时为空
            // Check if both file and fileUrl are null
            if (createOutlineByDoc.file == null && string.IsNullOrWhiteSpace(createOutlineByDoc.fileUrl))
            {
                throw new ArgumentException("Either file or fileUrl must be provided.");
            }
            if (string.IsNullOrWhiteSpace(createOutlineByDoc.fileName))
            {
                throw new ArgumentNullException("fileName is required");
            }
            MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
            if (!string.IsNullOrWhiteSpace(createOutlineByDoc.query))
            {
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.query!), "query");

            }

            if (createOutlineByDoc.file != null)
            {
                if (string.IsNullOrWhiteSpace(createOutlineByDoc.fileName))
                {
                    throw new ArgumentNullException("File name (with file extension; if file or fileUrl is provided, fileName is required).");
                }
                var fileContent = new ByteArrayContent(createOutlineByDoc.file!);
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
                multipartFormDataContent.Add(fileContent, "file", createOutlineByDoc.fileName!);
            }


            if (!string.IsNullOrWhiteSpace(createOutlineByDoc.fileUrl))
            {
                if (string.IsNullOrWhiteSpace(createOutlineByDoc.fileName))
                {
                    throw new ArgumentNullException("File name (with file extension; if file or fileUrl is provided, fileName is required).");
                }
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.fileUrl), "fileUrl");
            }

            if (!string.IsNullOrWhiteSpace(createOutlineByDoc.fileName))
            {
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.fileName), "fileName");
            }

            if (!string.IsNullOrWhiteSpace(createOutlineByDoc.businessId))
            {
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.businessId), "businessId");
            }

            if (createOutlineByDoc.search.HasValue)
            {
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.search.Value.ToString()), "search");
            }

            if (!string.IsNullOrWhiteSpace(createOutlineByDoc.language))
            {
                multipartFormDataContent.Add(new StringContent(createOutlineByDoc.language), "language");
            }

            string url = Url + "api/ppt/v2/createOutlineByDoc";
            string resjosn = await SendRequestByFormDataAsync(url: url, multipartFormData: multipartFormDataContent);
            CreateOutlineByDocResponse createOutlineByDocResponse = new CreateOutlineByDocResponse();
            createOutlineByDocResponse.RealJsonstring = resjosn;
            return createOutlineByDocResponse;
        }

        /// <summary>
        /// 基于用户提示、文档等相关内容同步生成PPT大纲。
        /// This method synchronously generates a PPT outline based on user prompts, documents, and other relevant content.
        /// </summary>
        /// <param name="createOutlineByDoc">包含生成PPT大纲所需参数的请求对象。The request object containing the parameters required to generate the PPT outline.</param>
        /// <returns>生成PPT大纲的响应对象。The response object for generating the PPT outline.</returns>
        /// <remarks>
        /// query参数不得超过8000字，上传文件支持pdf(不支持扫描件)、doc、docx、txt、md格式的文件，注意：txt格式限制100万字以内，其他文件限制10M。
        /// The query parameter should not exceed 8000 characters. Supported file formats for upload are pdf (scanned copies are not supported), doc, docx, txt, and md. Note that txt files are limited to within 1 million characters, and other files are limited to 10M.
        /// </remarks>
        public CreateOutlineByDocResponse CreateOutlineByDoc(CreateOutlineByDocRequest createOutlineByDoc)
        {
            Task<CreateOutlineByDocResponse> task = CreateOutlineByDocAsync(createOutlineByDoc);
            task.Wait();
            return task.Result;
        }
        /// <summary>
        /// 通过大纲生成PPT Async
        /// </summary>
        /// <param name="createPptByOutline"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public async Task<CreatePptByOutlineResponse> CreatePptByOutlineAsync(CreatePptByOutlineRequest createPptByOutline)
        {
            if (createPptByOutline == null)
            {
                throw new ArgumentNullException("CreatePptByOutlineRequest is not null");
            }

            if (string.IsNullOrWhiteSpace(createPptByOutline.query))
            {
                throw new ArgumentNullException("query is not null");
            }

            if (createPptByOutline.outline == null)
            {
                throw new ArgumentNullException("outline is not null");
            }
            JsonSerializerOptions options = new JsonSerializerOptions()
            { 
                Encoder= JsonSerializerOptions.Encoder,
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };
            string requestjson = System.Text.Json.JsonSerializer.Serialize(createPptByOutline, options);

            string url = Url + "api/ppt/v2/createPptByOutline";
            string resjosn = await SendRequestAsync(url: url, method: HttpMethod.Post,postData: requestjson);
            CreatePptByOutlineResponse createPptByOutlineResponse = new CreatePptByOutlineResponse();
            createPptByOutlineResponse.RealJsonstring = resjosn;
            return createPptByOutlineResponse;
        }

        /// <summary>
        /// 通过大纲生成PPT
        /// </summary>
        /// <param name="createPptByOutline"></param>
        /// <returns></returns>
        public CreatePptByOutlineResponse CreatePptByOutline(CreatePptByOutlineRequest createPptByOutline)
        {

            Task<CreatePptByOutlineResponse> task = CreatePptByOutlineAsync(createPptByOutline);
            task.Wait();
            return task.Result;
        }

    }
}
